﻿#pragma once
#include "common.h"

namespace anip
{
	// first rotate, then zoom, then translate
	struct Transform2D
	{
		vec2 offset = { 0, 0 };
		vec2 zoom = { 1, 1 };
		float rotation = 0;

		Transform2D() {}
		Transform2D(vec2 off, float z = 1, float rot = 0):
			offset(off), zoom(z), rotation(rot) {}
		Transform2D(vec2 off, vec2 z, float rot = 0) :
			offset(off), zoom(z), rotation(rot) {}

		mat3 toMatrix() const;

		Transform2D combine(const Transform2D& second) const
		{
			return {
				second.transform(offset),		// offset
				zoom * second.zoom,				// zoom
				rotation + second.rotation };	// rotation
		}

		Transform2D scaleAroundThisSystem(invec2 p, invec2 factor) const
		{
			return {
				(offset - p) * factor + p,		// offset
				zoom * factor,					// zoom
				rotation };						// rotation
		}

		Transform2D rotateAroundThisSystem(invec2 p, float rad) const
		{
			return {
				math::rotate(offset - p, rad) + p,	// offset
				zoom,								// zoom
				rotation + rad };					// rotation
		}

		Transform2D scaleAround(invec2 p, invec2 factor) const
		{
			vec2 pp = transform(p);
			return scaleAroundThisSystem(pp, factor);
		}

		Transform2D rotateAround(invec2 p, float rad) const
		{
			vec2 pp = transform(p);
			return rotateAroundThisSystem(pp, rad);
		}
		
		vec2 transform(invec2 p) const
		{
			return math::rotate(p, rotation) * zoom + offset;
		}

		void transformBoundingRect(outvec2 p, outvec2 s) const;
		void undoTransformBoundingRect(outvec2 p, outvec2 s) const;

		vec2 undoTransform(invec2 p) const
		{
			return math::rotate((p - offset) / zoom, -rotation);
		}
	};

	struct kTransform
	{
		// ANIP_TODO
	};
}